package com.onlyxiahui.framework.net.handler;

import java.util.HashSet;
import java.util.Random;
import java.util.Set;

import com.onlyxiahui.framework.net.handler.connect.Connector;
import com.onlyxiahui.framework.net.handler.connect.data.ConnectData;
import com.onlyxiahui.framework.net.handler.connect.type.IdleStatus;
import com.onlyxiahui.framework.net.handler.data.handler.MessageHandler;

/**
 * Description <br>
 * Date 2020-05-12 19:07:23<br>
 * 
 * @author XiaHui [onlovexiahui@qq.com]<br>
 * @since 1.0.0
 */

public class ConnectorImpl implements Connector {
	Random r = new Random();
	Set<MessageHandler> set = new HashSet<MessageHandler>();
	int count = 0;

	long sendLastTimestamp = 0;
	long receiveLastTimestamp = 0;
	long idleTimestamp = 1000 * 5;

	boolean connected = true;
	boolean connectedChange = false;
	boolean write = true;

	long connectedChangeIntervalTimestamp = 1000 * 8;
	long connectedChangeTimestamp = 0;

	long messageIntervalTimestamp = 1000 * 8;
	long messageTimestamp = 0;

	boolean run = true;

	public ConnectorImpl() {
		new Thread() {

			@Override
			public void run() {
				while (run) {
					handle();
					sleep();
				}
			}

			public void sleep() {
				try {
					sleep(200);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}.start();
	}

	void handle() {
		handeConnectedChange();
		handeMessage();
	}

	void handeConnectedChange() {
		long timestamp = System.currentTimeMillis();
		if (timestamp - connectedChangeTimestamp >= messageIntervalTimestamp) {

			int count = r.nextInt(15);
			count = count == 0 ? 1 : count;
			messageIntervalTimestamp = 1000 * count;

			connectedChange = !connectedChange;
			connectedChangeTimestamp = System.currentTimeMillis();
		}

	}

	void handeMessage() {
		long timestamp = System.currentTimeMillis();
		if (timestamp - messageTimestamp >= connectedChangeIntervalTimestamp) {
			int count = r.nextInt(10);
			count = count == 0 ? 1 : count;
			connectedChangeIntervalTimestamp = 1000 * count;

			message();
			messageTimestamp = System.currentTimeMillis();
		}
	}

	void message() {
		receiveLastTimestamp = System.currentTimeMillis();
		for (MessageHandler h : set) {
			h.receive("{}");
		}
	}

	@Override
	public boolean connect(ConnectData connectData) {
		connectedChange = true;
		return true;
	}

	@Override
	public boolean isConnected() {
		if (connectedChange) {
			connectedChange = false;
			connected = !connected;
		}
		return connected;
	}

	@Override
	public void close() {
		run = false;
	}

	@Override
	public boolean write(Object data) {
		if (write) {
			sendLastTimestamp = System.currentTimeMillis();
		}
		return write;
	}

	@Override
	public void addMessageHandler(MessageHandler handler) {
		set.add(handler);
	}

	@Override
	public IdleStatus getIdleStatus() {
		long timestamp = System.currentTimeMillis();

		IdleStatus status = IdleStatus.no;
		boolean sendIdle = timestamp - sendLastTimestamp > idleTimestamp;
		boolean receiveIdle = timestamp - receiveLastTimestamp > idleTimestamp;

		if (sendIdle && receiveIdle) {
			status = IdleStatus.all;
		} else if (sendIdle) {
			status = IdleStatus.write;
		} else if (receiveIdle) {
			status = IdleStatus.read;
		}
		return status;
	}
}
